/* ================================================================================
//	Crypteviant!
//	Providing tough encrypted P2P Chat
//	Copyright (C) 2010  Martin Pfeifer, Tobias Rausch
//
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.
// ============================================================================== */

#ifndef ENTROPYPOOLMANAGER_HPP
#define ENTROPYPOOLMANAGER_HPP

#include <QtCore/QThread>
#include <QtCore/QMap>
#include <QtCore/QMetaType>
#include <QtCore/QDateTime>
#include <QtCore/QVariant>
#include <QtCore/QDebug>

#include "entropypool.hpp"
#include "entropydatastruct.hpp"


namespace RandomPool
{

    /**
     * @brief Management class for EntropyPools
     * @details The EntropyPoolManager is implemented as a Singleton.\n
     * On its creation it will spawn a specified amount of EntropyPools.\n
     * The EntropyPoolManager runs in its own Thread so that the EntropySources can simply add data using
     * the signal/slot principle Qt provides.
     *
     * @class EntropyPoolManager entropypoolmanager.hpp "entropypoolmanager.hpp"
    */
    class EntropyPoolManager : public QThread
    {
        Q_OBJECT

    public:
        /**
         * @var POOLCOUNT
         * @brief The amount of Pools which are spawned
        */
        static const unsigned int POOLCOUNT = 32;

        /**
         * @var MAXLIFETIME
         * @brief Data older than this time (ms) will be ignored
        */
        static const unsigned int MAXLIFETIME = 60000;

    public:
        /**
         * @brief Get the global EntropyPoolManager instance
         * @details Only one EntropyPoolManager can be used at a time.
         *
         * @fn static getInstance()
         * @return const EntropyPoolManager *const
        */
        static const EntropyPoolManager * const getInstance();

        /**
         * @brief Implementation of QThreads run() method
         * @details This will set up the EntropyPools and start an own event loop.
         *
         * @fn run()
        */
        void run();

    private:
        /**
         * @brief Default Constructor
         * @details Private for singleton purpose
         *
         * @fn EntropyPoolManager(QObject*)
         * @param parent
        */
        explicit EntropyPoolManager(QObject *parent = 0);

        /**
         * @brief Default Destructor
         *
         * @fn ~EntropyPoolManager()
        */
        virtual ~EntropyPoolManager();

    public slots:
        /**
         * @brief Add Data to a Pool
         * @details The EntropyPoolManager runs in its own Thread.\n
         * If you add new data using the signal/slot principle of Qt (emitting a signal which is connected to this slot)
         * you need not care about the executing time, because it is performed asynchronously in another Thread.
         *
         * @fn addData(EntropyDataStruct)
         * @param data
        */
        void addData(EntropyDataStruct data);

    private:
        /**
         * @var m_instance
         * @brief Holding the static instance of the Manager
        */
        static EntropyPoolManager *m_instance;

        /**
         * @var m_pools
         * @brief All Pools are associated with its unique ID
        */
        QMap<unsigned int, EntropyPool*> m_pools;
    };

} // End of Namespace RandomPool

#endif // ENTROPYPOOLMANAGER_HPP
